import arcpy
from arcpy.sa import *
import tempfile
import os
import sys
import stormwaterutilities
from stormwaterutilities import addMessage

def AccumulateToNetwork(links, nodes, catchments, flowDirection, rasterToAccumulate, accumField, accumFactor=1.0):

    tempFolder = r"d:\temp"

    tempRaster = os.path.join(tempFolder, "temp.tif")
    tempRaster2 = os.path.join(tempFolder, "temp2.tif")
    tempRaster3 = os.path.join(tempFolder, "temp3.tif")

    arcpy.CheckOutExtension("Spatial")
    addMessage("Zeroing out null values in raster to accumulate ({0})...".format(rasterToAccumulate))
    nonnull_raster = Con(IsNull(rasterToAccumulate), 0, rasterToAccumulate)
    nonnull_raster.save(tempRaster)

    addMessage("Converting raster to accumulate to standard TIFF...")
    stormwaterutilities.gdalTranslate(tempRaster, tempRaster2)

    addMessage("Calculating local accumulation...")
    stormwaterutilities.tauD8Area(flowDirection, tempRaster2, tempRaster3, 6)

    args = ["Accumulate", links, nodes, catchments, flowDirection, tempRaster3, accumField, str(accumFactor)]
    addMessage("Executing AccumulateToNetwork with arguments: " + str(args))

    stormwaterutilities.callGpTool(args)

    try:
        arcpy.Delete_management(tempRaster)
        arcpy.Delete_management(tempRaster2)
        arcpy.Delete_management(tempRaster3)
    except:
        addMessage("Warning: Unable to delete all temporary accumulation rasters.")

class AccumulateToNetworkTool(object):
    def __init__(self):
        """Accumulates upstream area from a raster file to a conveyance network."""
        self.label = "Accumulate to Network"
        self.description = "Accumulates upstream area from a raster file to a conveyance network."
        self.canRunInBackground = True

    def getParameterInfo(self):
        """Define parameter definitions"""
        param0 = arcpy.Parameter(
            displayName="Conveyance Lines Feature Class",
            name="lines_fc",
            datatype="GPFeatureLayer",
            parameterType="Required",
            direction="Input")

        param0.filter.list = ['LINE']

        param1 = arcpy.Parameter(
            displayName="Conveyance Nodes Feature Class",
            name="nodes_fc",
            datatype="GPFeatureLayer",
            parameterType="Required",
            direction="Input")

        param1.filter.list = ['POINT']

        param2 = arcpy.Parameter(
            displayName="Catchment Feature Class",
            name="catchment_fc",
            datatype="GPFeatureLayer",
            parameterType="Required",
            direction="Input")

        param2.filter.list = ['POLYGON']

        param3 = arcpy.Parameter(
            displayName="Flow Direction Grid",
            name="flowdir",
            datatype="GPRasterLayer",
            parameterType="Required",
            direction="Input")

        param4 = arcpy.Parameter(
            displayName="Accumulation Grid",
            name="accum",
            datatype="GPRasterLayer",
            parameterType="Required",
            direction="Input")

        param5 = arcpy.Parameter(
            displayName="Accumulation Field",
            name="accum_field",
            datatype="GPString")

        param5.value = "accumulation"

        param6 = arcpy.Parameter(
            displayName="Conversion Factor",
            name="factor",
            datatype="GPDouble",
            direction="Input")

        param6.value = 1

        params = [param0, param1, param2, param3, param4, param5, param6]
        return params

    def isLicensed(self):
        """Set whether tool is licensed to execute."""
        return True

    def updateParameters(self, parameters):
        """Modify the values and properties of parameters before internal
        validation is performed.  This method is called whenever a parameter
        has been changed."""
        return

    def updateMessages(self, parameters):
        """Modify the messages created by internal validation for each tool
        parameter.  This method is called after internal validation."""
        return

    def execute(self, parameters, messages):
        """The source code of the tool."""

        (links, nodes, catchments, flowDirection, rasterToAccumulate, accumField, accumFactor) = stormwaterutilities.convertParametersToFullPathStrings(parameters)
        self.AccumulateToNetwork(links, nodes, catchments, flowDirection, rasterToAccumulate, accumField, accumFactor)
        return

"""
if __name__ == "__main__":
    print("accumulatetonetwork.py is being run directly with args:")

    print(sys.argv)

    AccumulateToNetwork(sys.argv)
else:
    #print("accumulatetonetwork.py is being imported into another module:" + __name__)

    #print(sys.argv)
"""
